﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using UnityCore;
using System.Data;
using System.Data.Odbc;
//using StoreClientModule;
//using DataManager;
using System.IO;

namespace UploadManager
{
    public struct readDetails
    {
        public string date;
        public string fileName;
        public List<string> fileNames;
        public string remNode;
    }
    public struct priceDetails
    {
        public List<DataTable> tables;
        public string txtSearch;
    }
    public struct autoDetails
    {
        public DataTable tbl;
        public string search;
    }
    public struct downloadDetails
    {
        public string date;
        public string remNode;
    }

    public class SynchronizeData : UnityProcessCall
    {
        FsDetails remDb = new FsDetails()
        {
            SVR = Common.oServer,
            UID = Common.oUID,
            PWD = Common.oPWD
        };


        string locPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        public SynchronizeData()
        {

        }

        StreamReader sr;
        public string[] stores;
        object [] bAutoSoldTo;
        object [] bAutoInvoice;

        public DataTable export;
        public List<DataTable> exportTables;
        public DataTable pPriceList;


        void pDownload(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Download";

            string updateDate = (string)p;
            string[] remNodes = new string[0];
            string[] Tables = new string[0];

            RemoteAccess rdb = new RemoteAccess(remDb);
            FormatAccess fa = new FormatAccess();
            try
            {
                string indata = "";
                string[] sDate = updateDate.Split('/');

                //read first textfile remNodes
                OnProcessProgress(proc.ID, "Getting Store.txt ...");
                sr = new StreamReader(AppDomain.CurrentDomain.BaseDirectory +"Store.txt");
                while((indata=sr.ReadLine())!=null)
                {
                    Array.Resize<string>(ref remNodes, remNodes.Length + 1);
                    
                    remNodes[remNodes.Length - 1] = indata;
                }
                //read second textfile tables
                OnProcessProgress(proc.ID, "Getting Tables.txt ...");
                string[] filePath = new string[0];
                string path;

                sr = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + "Tables.txt");
                while ((indata = sr.ReadLine()) != null)
                {
                    Array.Resize<string>(ref Tables, Tables.Length + 1);
                    Array.Resize<string>(ref filePath, filePath.Length + 1);

                    string fileName = "";
                    path = "";
                    if (indata.Contains('_'))
                    {
                        fileName = indata + "" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                        path = "/" + sDate[2] + "/" + sDate[0] + "/" + sDate[1];
                    }
                    else
                    {
                        fileName = indata + ".uff";
                        path = "";
                    }
                        Tables[Tables.Length - 1] = fileName;
                        filePath[filePath.Length - 1] = path;
                }
                
                //download the files 
                OnProcessProgress(proc.ID, "Connecting to the server...");
                
                for (int i = 0; i < remNodes.Length; i++)
                {
                    
                    rdb.GetDirectoryList(remNodes[i], false);
                    string[] dList = rdb.Directories;
                    for (int j = 0; j < Tables.Length; j++)
                    {
                        bool found = false;
                        for (int k = 0; k < dList.Length; k++)
                        {
                            if (Tables[j].Equals(dList[k]))
                            {
                                found = true;
                                break;
                            }
                        }
                        if (found == true)
                        {
                            rdb.GetFileSize(remNodes[i] + "/" + Tables[j]);
                            long sz = rdb.FileSize;
                            OnProcessProgress(proc.ID, "Getting the Records..."+remNodes[i]+ ":" + Tables[j] + " - " + sz);
                            string pf = locPath + "/" + remNodes[i] + "" + filePath[j];
                            if(!Directory.Exists(pf))
                                Directory.CreateDirectory(pf);

                            rdb.GetFile(remNodes[i] + "/" + Tables[j], pf + "/" + Tables[j], sz);
                            fa.Filename = pf + "\\" + Tables[j];
                            OnProcessProgress(proc.ID, "Download Completed...");
                        }
                    }
                }

                OnProcessProgress(proc.ID, "Finished...Thank you very much");
                    
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        void pDownload_02(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Download";

            downloadDetails download= (downloadDetails)p;
            
            //string updateDate = (string)p;
            //string[] remNodes = new string[0];
            string[] Tables = new string[0];

            RemoteAccess rdb = new RemoteAccess(remDb);
            FormatAccess fa = new FormatAccess();
            try
            {
                string indata = "";
                string[] sDate = download.date.Split('/');

                //read second textfile tables
                OnProcessProgress(proc.ID, "Getting Tables.txt ...");
                string[] filePath = new string[0];
                string path;

                sr = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + "Tables.txt");
                while ((indata = sr.ReadLine()) != null)
                {
                    Array.Resize<string>(ref Tables, Tables.Length + 1);
                    Array.Resize<string>(ref filePath, filePath.Length + 1);

                    string fileName = "";
                    path = "";
                    if (indata.Contains('_'))
                    {
                        fileName = indata + "" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                        path = "/" + sDate[2] + "/" + sDate[0] + "/" + sDate[1];
                    }
                    else
                    {
                        fileName = indata + ".uff";
                        path = "";
                    }
                    Tables[Tables.Length - 1] = fileName;
                    filePath[filePath.Length - 1] = path;
                }

                //download the files 
                OnProcessProgress(proc.ID, "Connecting to the server...");


                    rdb.GetDirectoryList(download.remNode, false);
                    string[] dList = rdb.Directories;
                    for (int j = 0; j < Tables.Length; j++)
                    {
                        bool found = false;
                        for (int k = 0; k < dList.Length; k++)
                        {
                            if (Tables[j].Equals(dList[k]))
                            {
                                found = true;
                                break;
                            }
                        }
                        if (found == true)
                        {
                            rdb.GetFileSize(download.remNode + "/" + Tables[j]);
                            long sz = rdb.FileSize;
                            OnProcessProgress(proc.ID, "Getting the Records..." + download.remNode + ":" + Tables[j] + " - " + sz);
                            string pf = locPath + "/" + download.remNode + "" + filePath[j];
                            if (!Directory.Exists(pf))
                                Directory.CreateDirectory(pf);

                            rdb.GetFile(download.remNode + "/" + Tables[j], pf + "/" + Tables[j], sz);
                            fa.Filename = pf + "\\" + Tables[j];
                            OnProcessProgress(proc.ID, "Download Completed...");
                        }
                    }

                OnProcessProgress(proc.ID, "Finished...Thank you very much");

            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }

        void pAutoAccountName(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Auto";
            readDetails path = (readDetails)p;

            export = new DataTable();
            FormatAccess fa = new FormatAccess();
            try
            {
                string file = locPath + "/" + path.remNode;
                if (Directory.Exists(file))
                {
                    fa.Filename = file + "\\" + path.fileName + ".uff";
                    export = fa.Read("elayorbulc").Data;

                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        void pReadMany(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "ReadMany";
            readDetails path = (readDetails)p;
            
            export = new DataTable();
            FormatAccess fa = new FormatAccess();
            try
            {
                object theLock = new object();
                lock (theLock)
                {
                    if (!path.date.Equals(""))
                    {
                        string[] sDate = path.date.Split('/');
                        exportTables = new List<DataTable>();
                        for (int i = 0; i < path.fileNames.Count; i++)
                        {
                            exportTables.Add(new DataTable());
                            string file = locPath + "/" + path.remNode + "/" + sDate[2] + "/" + sDate[0] + "/" + sDate[1];
                            if (Directory.Exists(file))
                            {
                                fa.Filename = file + "\\" + path.fileNames[i] + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2] + ".uff";
                                if (File.Exists(fa.Filename))
                                {
                                    exportTables[i] = fa.Read("elayorbulc").Data;
                                }
                                else
                                {
                                    exportTables[i] = new DataTable();
                                }
                            }
                            else
                            {
                                proc.HasError = true;
                                proc.Msg = "File Not Found";
                            }
                        }
                    }
                    else
                    {
                        exportTables = new List<DataTable>();
                        for (int i = 0; i < path.fileNames.Count; i++)
                        {
                            exportTables.Add(new DataTable());
                            string file = locPath + "/" + path.remNode;
                            if (Directory.Exists(file))
                            {
                                fa.Filename = file + "\\" + path.fileNames[i] + ".uff";
                                if (File.Exists(fa.Filename))
                                {
                                    exportTables[i] = fa.Read("elayorbulc").Data;
                                }
                                else
                                {
                                    exportTables[i] = new DataTable();
                                }
                            }
                            else
                            {
                                proc.HasError = true;
                                proc.Msg = "File Not Found";
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        void pRead(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "Read";
            readDetails path = (readDetails)p;
            export = new DataTable();
            FormatAccess fa = new FormatAccess();
            try
            {
                string[] sDate = path.date.Split('/');
                string file = locPath + "/" + path.remNode + "/" + sDate[2] + "/" + sDate[0] + "/" + sDate[1];
                if (Directory.Exists(file))
                {
                    fa.Filename = file + "\\" + path.fileName + "_" + sDate[0] + "_" + sDate[1] + "_" + sDate[2]+".uff" ;
                    export = fa.Read("elayorbulc").Data;
                }
                
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        void pStores(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "GetStores";
            string indata = "";
            stores = new string[0];
            try
            {
                sr = new StreamReader(AppDomain.CurrentDomain.BaseDirectory + "Store.txt");
                while ((indata = sr.ReadLine()) != null)
                {
                    Array.Resize<string>(ref stores, stores.Length + 1);
                    stores[stores.Length - 1] = indata;
                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
        }
        void pAutoInvoiceNumber(object p, out object e)
        {
            UnityProcess proc = new UnityProcess() { ID = "AutoInvoice" };
            autoDetails str = (autoDetails)p;
            try
            {

                object theLock = new object();
                lock (theLock)
                {
                    bAutoInvoice = new object[0];
                    int ctr = 0;

                    for (int i = 0; i < str.tbl.Rows.Count; i++)
                    {
                        string indata = str.tbl.Rows[i]["fInvoice"].ToString();
                        string data = str.search.ToUpper();
                        if (indata.StartsWith(data))
                        {
                            Array.Resize<object>(ref bAutoInvoice, bAutoInvoice.Length + 1);
                            bAutoInvoice[bAutoInvoice.Length - 1] = str.tbl.Rows[i]["fInvoice"];
                            ctr++;
                        }
                        if (ctr == 5)
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = "Error getting invoice autofill.";
            }
            finally
            {
                e = proc;
            }
        } //end of autoSoldTo
        void pAutoSoldTo(object p, out object e)
        {
            UnityProcess proc = new UnityProcess() { ID = "AutoSoldTo" };
            autoDetails str = (autoDetails)p;
            try
            {
                
                object theLock = new object();
                lock (theLock)
                {
                    bAutoSoldTo = new object[0];
                    int ctr = 0;

                    for (int i = 0; i < str.tbl.Rows.Count; i++)
                    {
                        string indata = str.tbl.Rows[i]["fSoldTo"].ToString();
                        string data = str.search.ToUpper();
                        if (indata.StartsWith(data))
                        {
                            Array.Resize<object>(ref bAutoSoldTo, bAutoSoldTo.Length + 1);
                            bAutoSoldTo[bAutoSoldTo.Length - 1] = str.tbl.Rows[i]["fSoldTo"];
                            ctr++;
                        }
                        if (ctr == 5)
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = "Error getting soldto autofill.";
            }
            finally
            {
                e = proc;
            }
        } //end of autoSoldTo
        void extractPriceList(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "ExtractPriceList";
            priceDetails pd = (priceDetails)p;
            DataTable exportProducts = pd.tables[1];
            DataTable exportPriceList = pd.tables[0];
            try
            {
                pPriceList = new DataTable();
                //fSupplier, fBarcode, fDescription, fVariation, fP.Code, fMarkUp
                DataTable dt = new DataTable();
                dt.Columns.Add("fSupplier");
                dt.Columns.Add("fBarcode");
                dt.Columns.Add("fDescription");

                //pPriceList.Columns.Add("fSupplier");
                pPriceList.Columns.Add("fBarcode");
                pPriceList.Columns.Add("fDescription");
                pPriceList.Columns.Add("fVariation");
                pPriceList.Columns.Add("fPcode");
                pPriceList.Columns.Add("fMarkUp");

                DataRow dr0 = pPriceList.NewRow();
                //dr0["fSupplier"] = "Supplier";
                dr0["fBarcode"] = "Barcode";
                dr0["fDescription"] = "Description";
                dr0["fVariation"] = "Variation";
                dr0["fPcode"] = "P.Code";
                dr0["fMarkUp"] = "SRP";
                pPriceList.Rows.Add(dr0);

                //db.RecordQuery("SELECT * FROM tblProducts ORDER BY fSupplier ASC, fDescription ASC");
                //if (db.Count > 0)
                //{
                for (int i = 0; i < exportProducts.Rows.Count; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr["fSupplier"] = exportProducts.Rows[i]["fSupplier"].ToString();
                    dr["fBarcode"] = exportProducts.Rows[i]["fBarcode"].ToString();
                    dr["fDescription"] = exportProducts.Rows[i]["fDescription"].ToString();
                    dt.Rows.Add(dr);
                }
                //db.RecordQuery("SELECT fVariation, fPcode, fMarkUp, fBarcode FROM tblPriceList ORDER BY fBarcode ASC");
                for (int i = 0; i < dt.Rows.Count; i++)
                {

                    if (i > 0)
                    {
                        if (dt.Rows[i - 1]["fSupplier"].ToString() != dt.Rows[i]["fSupplier"].ToString())
                        {
                            DataRow dr = pPriceList.NewRow();
                            dr["fBarcode"] = "Supplier :";
                            dr["fDescription"] = dt.Rows[i]["fSupplier"];
                            pPriceList.Rows.Add(dr);
                        }
                    }
                    else
                    {
                        DataRow dr = pPriceList.NewRow();
                        dr["fBarcode"] = "Supplier :";
                        dr["fDescription"] = dt.Rows[i]["fSupplier"];
                        pPriceList.Rows.Add(dr);
                    }
                    DataRow dr1 = pPriceList.NewRow();
                    dr1 = pPriceList.NewRow();
                    dr1["fBarcode"] = dt.Rows[i]["fBarcode"];
                    dr1["fDescription"] = dt.Rows[i]["fDescription"];
                    pPriceList.Rows.Add(dr1);
                    string[] fVar = new string[0];
                    string[] fMup = new string[0];
                    string[] fPc = new string[0];

                    for (int j = 0; j < exportPriceList.Rows.Count; j++)
                    {
                        if (exportPriceList.Rows[j]["fBarcode"].ToString().Equals(dt.Rows[i]["fBarcode"].ToString()))
                        {
                            Array.Resize<string>(ref fVar, fVar.Length + 1);
                            Array.Resize<string>(ref fMup, fMup.Length + 1);
                            Array.Resize<string>(ref fPc, fPc.Length + 1);
                            int ind = fVar.Length - 1;
                            fVar[ind] = exportPriceList.Rows[j]["fVariation"].ToString();
                            fMup[ind] = exportPriceList.Rows[j]["fMarkUp"].ToString();
                            fPc[ind] = exportPriceList.Rows[j]["fPCode"].ToString();
                        }
                    }
                    if (fVar.Length > 0)
                    {
                        for (int j = 0; j < fVar.Length; j++)
                        {
                            DataRow dr2 = pPriceList.NewRow();
                            dr2["fVariation"] = fVar[j]; //db.RecordAt(cRow, "fVariation");
                            dr2["fPcode"] = Common.FormatEquivalent(fPc[j]); //General.FormatEquivalent(db.RecordAt(cRow, "fPCode"));
                            float percent = float.Parse(fMup[j]) / 100f;//float.Parse(db.RecordAt(cRow, "fMarkUp")) / 100f;
                            float pcode = float.Parse(fPc[j]);//float.Parse(db.RecordAt(cRow, "fPCode"));
                            float mu = (pcode * percent) + pcode;
                            dr2["fMarkUp"] = Common.FormatCurrency(mu.ToString());
                            pPriceList.Rows.Add(dr2);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }
            
        }
        void extractInventoryList(object p, out object e)
        {
            UnityProcess proc = new UnityProcess();
            proc.ID = "ExtractInventoryList";
            priceDetails pd = (priceDetails)p;
            string txtSearch = pd.txtSearch;

            DataTable exportWholeStock = pd.tables[0];
            DataTable exportRetailStock = pd.tables[1];
            DataTable exportPriceList = pd.tables[2];

            double whole = 0, retail = 0, price = 0, amount = 0;
            try
            {
                pPriceList = new DataTable();
                DataTable dt = new DataTable();
                dt.Columns.Clear();
                dt.Rows.Clear();

                dt.Columns.Add("Barcode");
                dt.Columns.Add("Supplier");
                dt.Columns.Add("Description");
                dt.Columns.Add("Stock");
                dt.Columns.Add("PCode");
                dt.Columns.Add("Amount");
                dt.Columns.Add("Content");

                for (int i = 0; i < exportWholeStock.Rows.Count; i++)
                {
                    if (exportWholeStock.Rows[i]["fBarcode"].ToString().Contains(txtSearch)
                        || exportWholeStock.Rows[i]["fDescription"].ToString().Contains(txtSearch))
                    {
                        DataRow dr = dt.NewRow();
                        dr["Barcode"] = exportWholeStock.Rows[i]["fBarcode"].ToString();
                        dr["Description"] = exportWholeStock.Rows[i]["fDescription"].ToString();
                        dr["Stock"] = exportWholeStock.Rows[i]["fQty"].ToString();
                        dt.Rows.Add(dr);
                    }
                }
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    for (int j = 0; j < export.Rows.Count; j++)
                    {
                        if (dt.Rows[i]["Barcode"].ToString().Equals(export.Rows[j]["fBarcode"].ToString()))
                        {
                            dt.Rows[i]["Supplier"] = export.Rows[j]["fSupplier"].ToString();
                            
                            break;
                        }
                    }
                    for (int k = 0; k < exportPriceList.Rows.Count; k++)
                    {
                        if (dt.Rows[i]["Barcode"].ToString().Equals(exportPriceList.Rows[k]["fBarcode"].ToString()))
                        {
                            dt.Rows[i]["PCode"] = exportPriceList.Rows[k]["fPCode"].ToString();
                            dt.Rows[i]["Content"] = exportPriceList.Rows[k]["fContent"].ToString();
                            
                            break;
                        }
                    }
                }
                pPriceList = dt;
            }
            catch (Exception ex)
            {
                proc.HasError = true;
                proc.Msg = ex.Message;
            }
            finally
            {
                e = proc;
            }

        }
        //Exposed Members
        public void AutoSoldTo(autoDetails str)
        {
            ThreadHandler ao = new ThreadHandler(pAutoSoldTo);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object e;
            IAsyncResult ar = ao.BeginInvoke(str, out e, ac, null);
        }
        public void AutoInvoice(autoDetails str)
        {
            ThreadHandler ao = new ThreadHandler(pAutoInvoiceNumber);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object e;
            IAsyncResult ar = ao.BeginInvoke(str, out e, ac, null);
        }
        public void Download(string upD)
        {
            ThreadHandler th = new ThreadHandler(pDownload);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(upD, out o, ac, null);
        }
        public void Download_02(downloadDetails upD)
        {
            ThreadHandler th = new ThreadHandler(pDownload_02);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(upD, out o, ac, null);
        }
        public void Auto(readDetails path)
        {
            ThreadHandler th = new ThreadHandler(pAutoAccountName);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(path, out o, ac, null);
        }
        public void Read(readDetails path)
        {
            ThreadHandler th = new ThreadHandler(pRead);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(path, out o, ac, null);
        }
        public void ReadMany(readDetails path)
        {
            ThreadHandler th = new ThreadHandler(pReadMany);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(path, out o, ac, null);
        }
        public void Stores()
        {
            ThreadHandler th = new ThreadHandler(pStores);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(null, out o, ac, null);
        }
        public void extract(priceDetails path)
        {
            ThreadHandler th = new ThreadHandler(extractPriceList);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(path, out o, ac, null);
        }
        public void extractStock(priceDetails path)
        {
            ThreadHandler th = new ThreadHandler(extractInventoryList);
            AsyncCallback ac = new AsyncCallback(GenericCB);
            object o;
            IAsyncResult ar = th.BeginInvoke(path, out o, ac, null);
        }
        public object[] ListAutoSoldTo
        {
            get { return bAutoSoldTo; }
        }
        public object[] ListAutoInvoice
        {
            get { return bAutoInvoice; }
        }
    }

    public struct NodeType
    {
        public string Key;
        public string Value;
    }
    public struct SettingType
    {
        public string Section;
        public NodeType[] Node;
    }
    public struct UpdateType
    {
        public string fUpdateKey;
        public string fFlag;
        public string fRemarks;
    }
    public struct UploadType
    {
        public string fUpdateKey;
        public string fPKey;
        public string fParentTable;
        public string fParentKey;
        public string fRemarks;
        public string fFlag;
    }
    static class Common
    {
        //Local Connection
        public static string lUID = "";
        public static string lPWD = "";
        public static string lDatabase = "";
        public static string lServer = "";
        public static string lStoreID = "";
        public static string lStoreName = "";
        public static string lStoreAddress = "";

        //Online Connection
        public static string oUID = "";
        public static string oPWD = "";
        public static string oDatabase = "";
        public static string oServer = "";
        //Update Buffer
        public static UpdateType[] Updates = new UpdateType[0];
        public static UploadType[] Uploads = new UploadType[0];
        //User
        public static string Username = "";
        public static string Password = "";
        public static bool UserLogged = false;
        public static float GetVolumeFactor(string fBase, string fTo)
        {
            float retVal = 0f;
            //Indices
            int x = -1, y = -1;
            //Volume Table
            string[] bV = { "LTR", "ML", "GAL" };
            string[] tV = { "LTR", "ML", "GAL" };
            float[][] vV = new float[3][];
            vV[0] = new float[] { 1f, 1000f, 0.25f };
            vV[1] = new float[] { 0.001f, 1f, 0.00025f };
            vV[2] = new float[] { 4f, 4000f, 1f };

            for (int i = 0; i < bV.Length; i++)
            {
                if (fBase == bV[i])
                {
                    x = i;
                    break;
                }
            }
            for (int i = 0; i < tV.Length; i++)
            {
                if (fTo == tV[i])
                {
                    y = i;
                    break;
                }
            }
            if (x == -1 || y == -1)
            {
                retVal = -1f;
            }
            else
            {
                retVal = vV[x][y];
            }
            return retVal;
        }
        public static float GetWeightFactor(string fBase, string fTo)
        {
            float retVal = 0f;
            //Indices
            int x = -1, y = -1;
            //Weight Table
            string[] bV = { "KG", "G" };
            string[] tV = { "KG", "G" };
            float[][] vV = new float[2][];
            vV[0] = new float[] { 1f, 1000f };
            vV[1] = new float[] { 0.001f, 1f };

            for (int i = 0; i < bV.Length; i++)
            {
                if (fBase == bV[i])
                {
                    x = i;
                    break;
                }
            }
            for (int i = 0; i < tV.Length; i++)
            {
                if (fTo == tV[i])
                {
                    y = i;
                    break;
                }
            }
            if (x == -1 || y == -1)
            {
                retVal = -1f;
            }
            else
            {
                retVal = vV[x][y];
            }
            return retVal;
        }
        public static float GetLengthFactor(string fBase, string fTo)
        {
            float retVal = 0f;
            //Indices
            int x = -1, y = -1;
            //Length Table
            string[] bV = { "M", "F" };
            string[] tV = { "M", "F" };
            float[][] vV = new float[2][];
            vV[0] = new float[] { 1f, 3.28f };
            vV[1] = new float[] { 0.3048f, 1f };

            for (int i = 0; i < bV.Length; i++)
            {
                if (fBase == bV[i])
                {
                    x = i;
                    break;
                }
            }
            for (int i = 0; i < tV.Length; i++)
            {
                if (fTo == tV[i])
                {
                    y = i;
                    break;
                }
            }
            if (x == -1 || y == -1)
            {
                retVal = -1f;
            }
            else
            {
                retVal = vV[x][y];
            }
            return retVal;
        }
        public static string FormatCurrency(string value)
        {
            string res = "";
            try
            {
                float val = float.Parse(value);
                res = val.ToString("#,0.00");
            }
            catch (Exception ex)
            {
            }
            return res;
        }
        public static string FormatCurrency(double num)
        {
            string value = "";
            try
            {
                value = num.ToString("#,#0.00");
            }
            catch (Exception ex)
            {
                value = ex.Message;
            }
            return value;
        }
        public static string FormatPercent(string value)
        {
            string res = "";
            try
            {
                float val = float.Parse(value);
                res = val.ToString("#0.00");
            }
            catch (Exception ex)
            {
            }
            return res;
        }
        public static string FormatNumber(string value)
        {
            string res = "";
            try
            {
                float val = float.Parse(value);
                res = val.ToString("#,#.##");
            }
            catch (Exception ex)
            {
            }
            return res;
        }
        public static string FormatEquivalent(string value)
        {
            char[] equi = { 'K', 'S', 'A', 'N', 'Y', 'O', 'Q', 'U', 'I', 'C' };
            char[] cArr = value.ToCharArray();
            int[] ibuf = new int[cArr.Length];
            string res = "";
            for (int i = 0; i < cArr.Length; i++)
            {
                if (cArr[i] != ',' && cArr[i] != '.')
                {
                    ibuf[i] = int.Parse(cArr[i].ToString());
                    res += equi[ibuf[i]];
                }
                else if (cArr[i] == '.')
                {
                    res += ".";
                }

            }
            return res;
        }
        public static string[] ListFinder(string[] lst, string str)
        {
            List<string> lt = new List<string>();
            lt.AddRange(lst);
            SearchDel search = dat =>
            {
                string[] l;
                l = lt.FindAll(n => n.Contains(dat)).ToArray();
                return l;
            };
            return search(str);
        }
        public static void WriteSettings(SettingType[] cfg)
        {
            using (StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBBClient.Txt"))
            {
                try
                {
                    string dat = "";
                    for (int i = 0; i < cfg.Length; i++)
                    {
                        dat += "[" + cfg[i].Section + "]\r\n";
                        for (int j = 0; j < cfg[i].Node.Length; j++)
                        {
                            dat += cfg[i].Node[j].Key + "=" + cfg[i].Node[j].Value + "\r\n";
                        }
                    }

                    sw.Write(dat);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    sw.Close();
                }
            }
        }
        public static SettingType[] ReadSettings()
        {
            SettingType[] cfg = new SettingType[0];
            string dat = "", str = "";
            int NewSect = 0, NewNode = 0;
            using (StreamReader sr = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBBClient.Txt"))
            {
                try
                {
                    while ((str = sr.ReadLine()) != null)
                    {
                        if (str.StartsWith("["))
                        {
                            NewSect = cfg.Length + 1;
                            NewNode = 0;
                            Array.Resize<SettingType>(ref cfg, NewSect);
                            cfg[NewSect - 1].Section = str.Substring(1, str.Length - 2);
                        }
                        else if (!str.StartsWith("[") && cfg.Length > 0 && !str.Equals(""))
                        {
                            if (NewNode == 0)
                            {
                                cfg[NewSect - 1].Node = new NodeType[0];
                            }
                            NewNode = cfg[NewSect - 1].Node.Length + 1;
                            Array.Resize<NodeType>(ref cfg[NewSect - 1].Node, NewNode);
                            string[] buf = new string[2];
                            string s = "";
                            for (int i = 0; i < str.Length; i++)
                            {
                                s = str.Substring(i, 1);
                                if (!s.Equals("="))
                                {
                                    buf[0] += s;
                                }
                                else
                                {
                                    i++;
                                    buf[1] = str.Substring(i);
                                    break;
                                }
                            }
                            cfg[NewSect - 1].Node[NewNode - 1].Key = buf[0];
                            cfg[NewSect - 1].Node[NewNode - 1].Value = buf[1];
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    sr.Close();
                }
                return cfg;
            }
        }
        public static MBBStoreClient.frmMain parent;
    }
    public delegate string[] SearchDel(string dat);
    public delegate void ModuleEventHandler(string procCode, string msg);
    public delegate void ModuleEventsHandler(int procCode, string msg);

    //MBB_Client
    public struct SalesItemType
    {
        public string fInvoice;
        public string fBarcode;
        public string fQty;
        public string fUnit;
        public string fDescription;
        public string fUnitPrice;
        public string fContentBarcode;
        public string fContentQty;
        public string fContentUnit;

    }
    public struct SalesType
    {
        public string fStoreID;
        public string fSoldTo;
        public string fAddress;
        public string fTelNo;
        public string fSalesman;
        public string fRef;
        public string fTerms;
        public string fPercentage;
        public string fORNum;
        public string fInvoice;
        public string fInvoiceType;
        public string fDate;
        public string fPO;
        public SalesItemType[] Items;
        public SalesItemType[] SubItems;
    }
    public struct SalesAmountType
    {
        public string fInvoice;
        public string fAmount;
    }
    public struct DailySalesType
    {
        public string fDate;
        public string fSalesman;
        public string fTotal;
        public SalesAmountType[] fSale;
    }
}
